package com.foolishbird.sdk.utils;



import com.foolishbird.sdk.secret.Base64;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class RSAUtil {

    private static final String publicKey =
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm1CtpxXQIuRIoH7zZO2NLU7px7xFsBT7WaD41+RPq/Z1pk3oVe3a7BmaBjQN0ZMxcwfXtwf75079YDj/RuGViX4Onrohu08siitOqnVt/4AahM7g7gklcOzuMepYro0Si1YNnZfxZI8ZvXF3CNFARo3jDCQsAsoXcsqz9KAlSKLybjpGnwucGbK51wOlrzZ7MRRtwDQIFCbnCk5bkV4Q7SNq/gCc83c0DOavX+qyefwh1JxAe+DC39TMOQsYUa4bEAOfrr8Io23+6C6WzLHZoPhrPd7XvA2EfQSMGtFn8I3KHdj5Mn/Lf3Zh8mJnrx5kXAKRsOiGtNhDXt1UGnnpOwIDAQAB"
//            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhiTdaCfpKrlF+JTw9dQon9q2hUUOEtn56s6XUGTeqxCB7Ni8kWQ3W/17d6AvjhLj2x69qONIR9b+BcxcOw9nkOvduSZeZLU5/i73PZFWw54Y60eQ/fCHtEAXinXVmV5rrTCoX+qL2dfpWcnWSThRDcJ7cDBDw2fwDAf3MpS1SUe4F0hikZ/gTIckWJp/G61uFVdQT/tMGgl/Kx8eBT9EZOc6Lp6Hiy/6uWEDubxT8FFoDSZDq/WvnFgPnDJ9CWyQFKCjDz5txXT9yi+vGIhAWUjiLL4vyriwC9lPZR3beN0llJbcwxveV+JvsqxQJq3vp6JBy7r/gzO9afViCVxRvQIDAQAB"
            ;
    private static final String prilicKey =
            "MIIEogIBAAKCAQEA0DQCuTYYShrgrdhP2iMGktIk5cMxVWWDBktaaF1ZXEAOiBxK\n" +
                    "tYAGfstAt1wexhUSfUOuED1zg4EG18VlAEv4g6GBiD4nwSoyFv0Gck2bQaEr4UE4\n" +
                    "fu2B/RLbvhpTIUH9KV6QNDoSkWL7/QNQ6plEs1rHs+I7X4mc3Daljc4bWT4l6L7f\n" +
                    "kSujdDlLGh7l8azUx60Uh4209T+sL8qj2YCF577Q0D/VYjj1nPplrXEtmwvVTo5F\n" +
                    "B1pgba6sUF35PoaEva1tThHIM1LdmkSvVAL/zqY58OU6cuV0eH2a4DblEkat8IWf\n" +
                    "++98YaOBrWTl8VxAKkGwMGg9vp17rirLas6xrwIBIwKCAQEAuGiUsqxBZjUQJPLK\n" +
                    "Yh8F0n+dBgSoCc7wZKkkMI0x4/44wbKokiDvz2ORF27ZbZ2iqXZ1mVr/6YDozb12\n" +
                    "tx63ioe73xJ6+4vF9xqfT0wNK4AfjP9Aqu+fBLjug84sX0kTbcjI3c0JIa9xebJ6\n" +
                    "3mp+rXxKesEQBCltrRp1YFd3TwmOhI5Goe/NxzbH4ymYL4C5C+5mUYxHp63kGdC9\n" +
                    "m85Xoa5Xqy0slfMQzxlNTxs83A42nW0/oRqvv65CnxjzdIeuSXl91qvMiVi+C/sj\n" +
                    "+iVCx8q156cqGcFIiGno5SFoFfFVpfLjLjqf1Io89ruGiAOG7AjG8/FKEtensiJS\n" +
                    "Yec+wwKBgQD61HgcbcjDKEUfdHw/HRdooeuNxGKpZViBWa/qm10kWQvm3ztSEOjj\n" +
                    "1thGXim8Ly6Go52aUIXCMi4hPb+5FekX3cfCBp7/JXE8jrJk8FZP3Wx0STDugp0w\n" +
                    "xwZuiidQ9BEx8HN4PSaAL9h++UEZaql9Z5NJnvKof/G59/CuTpA5OwKBgQDUfp3e\n" +
                    "vyKU3qXOGMZFVKD+Uhd2VpTsNa850btvjjpp+TAj3SxZPKj+y8u/xGrBWqP4O0PF\n" +
                    "+K465zerNbOg5x0C8Anrp6iPi5Y11MERQP59UbgAiWLq23ZMo9ZOrjQvHjWGp85h\n" +
                    "DrhYQdQYtlhVqxHgG0mm+elJ3xMdJuoSrbVCHQKBgA5VSLEq2EWqh5tlvfT6WRvr\n" +
                    "/tTmpo1WP5Jc5Xse0h9Vi6bK7XJnXcPgZCFHNZW5jaFLLZPKFkWcd6ogySCE6L+J\n" +
                    "BBm3PEkYFRlnPWTaiJbZc+ljRJ/qNN43QjIzx7t7qTYNvXSVx6+NtJmKlgFzzyu8\n" +
                    "xpZ+HH6oObLa989yNCCHAoGADCR+DLp3ATFLTZsEA/Y1FdjOJATykSejnOdpy9w9\n" +
                    "2it/F/4CiMGjQcKAq99WjrS46Zz8jvhEeGT73eXPwA0025iwHBg1hIuiLvY26wsH\n" +
                    "Olxw6hZ6rlWu/RCtKRFEz34Rr+xU75pw7xm0WS79u8Ch74yH3afhce99b2FPNERw\n" +
                    "wfMCgYEAvEm+DExI386VAWRKRh9/uqC1iDFo9jTsFwWe0v0z5P5Q+fMdlrqdFAwR\n" +
                    "uJYwP8oNpdkDfvJc0L/da311nKloNIL7P451Zbng5tCSfZXbFZmniZfWPNYu2GtK\n" +
                    "g1bEfDS1+rJOaKWiufUlalyFAQOZY4TakoiHMJlLf6x/74waFJc=";
//            "MIIEpAIBAAKCAQEAmc9TVPEbOQXLD0inlyrkMxSFsg44nskmIofgHUycxfFItAEvrIv7iTmEmXu6dOFI3+SiIt6+nyZTdS2uKZdgz5VgosSzY1qVUTNqqTS7bC6KWtNn0eYsac7PpVGv8JS+QN91UUlDjr5R416brH1U/X4NHaolCfND3bIt5ABra31s1MwWJKIIyUAXOVxe6/ABfykV5DZIG6ao2e9vL3SP4jpHhuFhhiU1hlODEMgno/2B5mWBoLugP5El8FnTUwHUBxtDhE7E/UdyVtcnML0FOAFV6vtVGMmRWMcflFmwVQoSsShTWi/BXWlURJs6rowQafpNjNfjJVdtfK3An/undQIDAQABAoIBACPwNodlYrf7K4whrM78fZ+VzvtgqUgotdlhqDMQYJ07mII+uLX3a0mP//Sg3VtL/GwcDupY429qVBvQFZ6wOTWnsJG3pjazxqnXereYk6ZeZYN9XAfGYWBDq270XEi5aI7d55qbpMZon9ehlnxCOKaWWlgxFkBx78yQQnrAwli18w/LG1nimmMyGHpQwdmM8qFqTaUh84RdqKUyLp1+/beTKWkT6E501pF1xK5wUplKVxKH4iQP/vhsw96X/FhVxkxkYymdxX+T9aadqF9d4NfRMgBMHPYrT7tN4SwGzfcFoHes/FCjqCofwSW5+Q3sKG+dHR6UVDF3tQnISfUo9AECgYEA5Wftkg5nxGpwH3IVsQgnoE13yn/ZKS5XhsiZ0fNUEbfJul4kamH/L73zyx94VwoT5lTWKdyQesWm/CejIuuCploS8go55e+/LU3M6+X0ZINEmnQ6ilrFonNPp/4BR41vtlL3x/jadu0if+cZxm5yAsyAsMlhAod6Moh/6E7tYnUCgYEAq6PvVOjFyhl+AYBWpFsAOxrXJIQM/4aO9icFNGLV09XMoicYMCjcS+z69TXBJPL4KbBfIlZHruPCeF5XLmJpnlnqr102AQ0SwZtdq6Kui2EQW5zEe3YsoEMcFF5blfiK+ORPI2KJjdCoAXY+/Np8v8woorynGGyU6tEu5w3ikQECgYEAofsvOXkodfz97IY+oMD0UfFBS1/Ys4ZAUTBlxGQ/ET+nlguRRPirGkfS07MF4td/05xFmEtgTQAw90z5mNeYaeOiCvuDhEMzx0ZvEoZNeYdisnitOTH86MbpEOJ+fsp0fdW5lZ62i1DHkm5Yuc8Ue7twhuO6tvF4LCRLxHmujl0CgYEAnA6ytY3q/+ULt0u7+zWuUQ8HW/EgbFgotdAmoEnYxwFWTHylNmyAWBxA1SCp2vF7B1SQOwUdqfr1v0FvnQHnrA1vH0DtsCj1y8h6c2q3roxzNgikcOiyjIhYCID+Xq4blU7oUXDvRlzX1HRxsq7oy+5RaB2FA+T9xT6qmXP7cwECgYAYTbKIHCPQ4j9gyJQX1sMvebqREeSyYMcoDb2fsS5Z8UvKab+Dsr5L+A0I56+xsKId2av5hgVHABP2owC5jbwzo4RSCVAVtUlnzbSN8WibM5AFIhO0yWeNogFHkoLvT5mJs0nZ2TrLM5ioj20in2pSf+y6r0qsxIiZmcooW9WHAw==";

//        private static final String publicKey = "-----BEGIN PUBLIC KEY-----\n" +
//        "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuADANXXWSc18nJQ5nCMf\n" +
//        "Qsmj5Ql5lNB5ERaicSNAR2Nb1KF9Qtgq2TSW4E+sPeF6P5iQxzxSiDoqfJP3IzHA\n" +
//        "JQvB/pB4kEYfI0EKfMd6hw4isIqOsmz98/E5AGQZ42nwFD8Lw8uh/t9clSiKJTJW\n" +
//        "sS4FYVcFhNhZd+kkp1Sbgql/fJB/Tc3GcKuj7dN3gfUY9FJpjmpMfJWtufGIXkgb\n" +
//        "VDP33qBGXN01uTR9EBMpdTIaVovZZ9FCCI2r1uQ33Ups7Di7X076r88L9LvCV1dH\n" +
//        "+o381oYY/xIf+HDnbK87PtOsUJR20ps0fpHxVZrv57v1uaC8aN9FoQSwXUesI/8f\n" +
//        "HwIDAQAB\n" +
//        "-----END PUBLIC KEY-----";

//    /**
//     * 用公钥对字符串进行加密
//     *
//     * @param data 原文
//     */
//    public static String encryptByPublicKey(byte[] data) {
//        try {
//
//
//            // 得到公钥
//            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey.getBytes());
//            KeyFactory kf = KeyFactory.getInstance("RSA");
//            PublicKey keyPublic = kf.generatePublic(keySpec);
//            // 加密数据
//            Cipher cp = Cipher.getInstance("ECB_PKCS1_PADDING");
//            cp.init(Cipher.ENCRYPT_MODE, keyPublic);
//            return new String(cp.doFinal(data));
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            return "";
//        }
//
//    }

    public static byte[] encryptByPublicKey(byte[] content) throws Exception {
        byte[] keyBytes = Base64.decode(publicKey, Base64.DEFAULT);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(x509KeySpec);
//        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = content.length;
//        StringBuilder sb = new StringBuilder();
//        for (int i = 0; i < inputLen; i += MAX_ENCRYPT_BLOCK) {
//            byte[] doFinal;
//            if(i+MAX_ENCRYPT_BLOCK>inputLen){
//                doFinal = cipher.doFinal(ArrayUtils.subarray(content, i, inputLen-i));
//            }else {
//                 doFinal = cipher.doFinal(ArrayUtils.subarray(content, i, i + MAX_ENCRYPT_BLOCK));
//            }
//
//            sb.append(new String(doFinal,"utf-8"));
//        }
//        return sb.toString().getBytes();


        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(content, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(content, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;

    }



    public static byte[] decryptByPrivateKey(byte[] content) throws Exception {
        byte[] keyBytes = Base64.decode(prilicKey,Base64.DEFAULT);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = content.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(content, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(content, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }





    /**
     * 将 Base64 字符串 解码成 字节数组
     */
    public static byte[] base64Decode(String data) {
        return Base64.decode(data, Base64.NO_WRAP);
    }



    /**
     * 处理异常
     */
    private static void handleException(Exception e) {
        e.printStackTrace();
    }



    private static final int MAX_ENCRYPT_BLOCK = 245;
    private static final int MAX_DECRYPT_BLOCK = 256;
    public static final String TRANSFORMATION = "RSA/None/PKCS1Padding";
    /**
     * 使用公钥将数据进行分段加密
     *
     * @param data   要加密的数据
     * @return 加密后的 Base64 编码数据，加密失败返回 null
     */
//    public static String encryptByPublicKey(String data) {
//        try {
//            byte[] bytes = data.getBytes("UTF-8");
////            // 创建 Cipher 对象
////            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
////            // 初始化 Cipher 对象，加密模式
////            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey));
//            // 得到公钥对象
//            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey.getBytes());
//            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//            PublicKey pubKey = keyFactory.generatePublic(keySpec);
//            // 加密数据
//            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
//            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
//            int inputLen = bytes.length;
//            // 保存加密的数据
//            ByteArrayOutputStream out = new ByteArrayOutputStream();
//            int offSet = 0, i = 0;
//            byte[] cache;
//            // 使用 RSA 对数据分段加密
//            while (inputLen - offSet > 0) {
//                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
//                    cache = cipher.doFinal(bytes, offSet, MAX_ENCRYPT_BLOCK);
//                } else {
//                    cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
//                }
//                // 将加密以后的数据保存到内存
//                out.write(cache, 0, cache.length);
//                i++;
//                offSet = i * MAX_ENCRYPT_BLOCK;
//            }
//            byte[] encryptedData = out.toByteArray();
//            out.close();
//            // 将加密后的数据转换成 Base64 字符串
//            return base64Encode(encryptedData);
//        } catch (Exception e) {
//            handleException(e);
//        }
//        return null;
//    }

/*    public static void newKey(){
        String data = "hello world";
        try {
            int keyLength = 2048;
            //生成密钥对
            KeyPair keyPair = generateRSAKeyPair(keyLength);
            //获取公钥
            byte[] publicKey = getPublicKey(keyPair);
            //获取私钥
            byte[] privateKey = getPrivateKey(keyPair);

            Log.e("Key",new String(publicKey));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }*/

    /** 生成密钥对，即公钥和私钥。key长度是512-2048，一般为1024 */
    public static KeyPair generateRSAKeyPair(int keyLength) throws NoSuchAlgorithmException {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(keyLength);
        return kpg.genKeyPair();
    }

    /** 获取公钥，打印为48-12613448136942-12272-122-913111503-126115048-12...等等一长串用-拼接的数字 */
    public static byte[] getPublicKey(KeyPair keyPair) {
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        return rsaPublicKey.getEncoded();
    }

    /** 获取私钥，同上 */
    public static byte[] getPrivateKey(KeyPair keyPair) {
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        return rsaPrivateKey.getEncoded();
    }

    /**
     * 将 字节数组 转换成 Base64 编码
     */
    public static String base64Encode(byte[] data) {
        return Base64.encodeToString(data, Base64.NO_WRAP);
    }



}

